package com.sojson.util.pay.wx;

import java.math.BigDecimal;
import java.util.List;

import com.alipay.api.response.AlipayFundTransOrderQueryResponse;
import com.sojson.base.impl.BaseOrder;
import com.sojson.config.exception.bean.Status;
import com.sojson.enums.core.EEnvironmentType;
import com.sojson.util.pay.wx.bean.WxResponseV2;
import com.sojson.util.pay.wx.bean.WxResult;
import com.sojson.util.pay.wx.constant.WxConstant;
import com.sojson.util.pay.wx.impl.WxPayOnlineUtil;
import com.sojson.util.pay.wx.impl.WxPayTestUtil;

/**
 * 微信支付工具类
 * 
 * @author liu
 * @date 2020-11-02
 */
public class WxPayUtil {

    private static final WxPayUtilInterface WX_PAY_UTIL = getWxPayUtil();

    /** ------------------------------R:必填----------------------------- */
    /** ------------------------------C:一定条件下可选--------------------- */
    /** ------------------------------O:可选----------------------------- */

    /**
     * 调起支付
     * 
     * @param order
     * @param notifyUrl
     * @return
     * @throws Exception
     */
    public static WxResult payWeb(BaseOrder order, String notifyUrl) throws Exception {
        return WX_PAY_UTIL.payWeb(order, notifyUrl);
    }

    /**
     * 调起合单支付
     * 
     * @param orders
     * @param notifyUrl
     * @return
     * @throws Exception
     */
    public static WxResult payMergeWeb(List<? extends BaseOrder> orders, String notifyUrl) throws Exception {
        return WX_PAY_UTIL.payMergeWeb(orders, notifyUrl);
    }

    /**
     * 调起支付
     * 
     * @param order
     * @param notifyUrl
     * @return
     * @throws Exception
     */
    public static WxResult payApp(BaseOrder order, String notifyUrl) throws Exception {
        return WX_PAY_UTIL.payApp(order, notifyUrl);
    }

    /**
     * 调起合单支付
     * 
     * @param orders
     * @param notifyUrl
     * @return
     * @throws Exception
     */
    public static WxResult payMergeApp(List<? extends BaseOrder> orders, String notifyUrl) throws Exception {
        return WX_PAY_UTIL.payMergeApp(orders, notifyUrl);
    }

    /**
     * 调起支付
     * 
     * @param order
     * @param notifyUrl
     * @return
     * @throws Exception
     */
    public static WxResult payXcx(BaseOrder order, String notifyUrl) throws Exception {
        return WX_PAY_UTIL.payXcx(order, notifyUrl);
    }

    /**
     * 调起合单支付
     * 
     * @param orders
     * @param notifyUrl
     * @return
     * @throws Exception
     */
    public static WxResult payMergeXcx(List<? extends BaseOrder> orders, String notifyUrl) throws Exception {
        return WX_PAY_UTIL.payMergeXcx(orders, notifyUrl);
    }

    /**
     * 调起支付
     * 
     * @param order
     * @param notifyUrl
     * @return
     * @throws Exception
     */
    public static WxResult payWap(BaseOrder order, String notifyUrl) throws Exception {
        return WX_PAY_UTIL.payWap(order, notifyUrl);
    }

    /**
     * 调起合单支付
     * 
     * @param orders
     * @param notifyUrl
     * @return
     * @throws Exception
     */
    public static WxResult payMergeWap(List<? extends BaseOrder> orders, String notifyUrl) throws Exception {
        return WX_PAY_UTIL.payMergeWap(orders, notifyUrl);
    }

    /**
     * 退款
     * 
     * @param order
     * @param notifyUrl
     * @return
     * @throws Exception
     */
    public static Status refund(BaseOrder order, String notifyUrl) throws Exception {
        return WX_PAY_UTIL.refund(order, notifyUrl);
    }

    /**
     * 关闭订单
     * 
     * @param orderNo   订单号
     * @return
     * @throws Exception
     */
    public static Status close(String orderNo) throws Exception {
        return WX_PAY_UTIL.close(orderNo);
    }

    /**
     * 关闭订单
     * 
     * @param payNo     微信支付单号
     * @param mchid     商户号
     * @param serialNo  商户 API 证书序列号
     * @return
     * @throws Exception
     */
    public static Status close(String orderNo, String mchid, String serialNo) throws Exception {
        return WX_PAY_UTIL.close(orderNo, mchid, serialNo);
    }

    /**
     * 查询支付订单
     * 
     * @param orderNo   订单号
     * @return
     * @throws Exception
     */
    public static Status queryByOrderNo(String orderNo) throws Exception {
        return WX_PAY_UTIL.queryByOrderNo(orderNo);
    }

    /**
     * 查询支付订单
     * 
     * @param payNo     微信支付单号
     * @param mchid     商户号
     * @param serialNo  商户 API 证书序列号
     * @return
     * @throws Exception
     */
    public static Status queryByOrderNo(String orderNo, String mchid, String serialNo) throws Exception {
        return WX_PAY_UTIL.queryByOrderNo(orderNo, mchid, serialNo);
    }

    /**
     * 查询支付订单
     * 
     * @param payNo 微信支付单号
     * @return
     * @throws Exception
     */
    public static Status queryByPayNo(String payNo) throws Exception {
        return WX_PAY_UTIL.queryByPayNo(payNo);
    }

    /**
     * 查询支付订单
     * 
     * @param payNo     微信支付单号
     * @param mchid     商户号
     * @param serialNo  商户 API 证书序列号
     * @return
     * @throws Exception
     */
    public static Status queryByPayNo(String payNo, String mchid, String serialNo) throws Exception {
        return WX_PAY_UTIL.queryByPayNo(payNo, mchid, serialNo);
    }

    /**
     * 查询退款订单
     * 
     * @param refundNo 退款单号
     * @return
     * @throws Exception
     */
    public static Status queryRefund(String refundNo) throws Exception {
        return WX_PAY_UTIL.queryRefund(refundNo);
    }

    /**
     * 查询退款订单
     * 
     * @param refundNo  退款单号
     * @param mchid     商户号
     * @param serialNo  商户 API 证书序列号
     * @return
     * @throws Exception
     */
    public static Status queryRefund(String refundNo, String mchid, String serialNo) throws Exception {
        return WX_PAY_UTIL.queryRefund(refundNo, mchid, serialNo);
    }

    /**
     * 单笔转账
     * 
     * @param orderNo   订单号
     * @param total     转账金额
     * @param openid    微信的唯一标识
     * @param name      用户姓名
     * @param title     转账原因
     * @return
     * @throws Exception
     */
    public static WxResponseV2 withdrawDeposit(String orderNo, BigDecimal total, String openid, String name,
        String title) throws Exception {
        return WX_PAY_UTIL.withdrawDeposit(orderNo, total, openid, name, title);
    }

    /**
     * 单笔转账
     * 
     * @param orderNo   订单号
     * @param mchid     商户号
     * @param mchKey    微信商户密钥(API密钥)
     * @param appid     Appid
     * @param total     转账金额
     * @param openid    微信的唯一标识
     * @param name      用户姓名
     * @param title     转账原因
     * @return
     * @throws Exception
     */
    public static WxResponseV2 withdrawDeposit(String orderNo, String mchid, String mchKey, String appid,
        BigDecimal total, String openid, String name, String title) throws Exception {
        return WX_PAY_UTIL.withdrawDeposit(orderNo, mchid, mchKey, appid, total, openid, name, title);
    }

    /**
     * 获取接口调用结果
     * 
     * @param res
     * @return
     */
    public static Status getStatus(WxResponseV2 res) {
        return WX_PAY_UTIL.getStatus(res);
    }

    /**
     * 查询转账订单
     * 
     * @param orderNo 商户订单号
     * @return
     * @throws Exception
     */
    public static AlipayFundTransOrderQueryResponse query(String orderNo) throws Exception {
        return WX_PAY_UTIL.query(orderNo);
    }

    private static WxPayUtilInterface getWxPayUtil() {
        Integer code = WxConstant.ENVIRONMENT;
        if (code == EEnvironmentType.ONLINE.getCode()) {
            return WxPayOnlineUtil.getInstances();
        } else if (code == EEnvironmentType.TEST.getCode()) {
            return WxPayTestUtil.getInstances();
        }
        return null;
    }

}